/*
 *
 *
Copyright (c) 1998-2001 Aristar, Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. The end-user documentation included with the redistribution, if any,
must include the following acknowledgment:

"This product includes software developed by Aristar, Inc. (http://www.aristar.com/)."

Alternately, this acknowledgment may appear in the software itself, if and
wherever such third-party acknowledgments normally appear.

4. The names "Dialect" and "Aristar, Inc." must not be used to endorse or
promote products derived from this software without prior written permission.
For written permission, please contact info@aristar.com.

5. Products derived from this software may not be called "Dialect", nor may
"Dialect" appear in their name, without prior written permission of Aristar, Inc.

THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
ARISTAR, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

This software consists of voluntary contributions made by many individuals
on behalf of Aristar, Inc.  For more information on Aristar, Inc.,
please see <http://www.aristar.com/>.

Portions of this software are based upon software freely available and
written by individuals not associated with Aristar, Inc.  Copyrights are
maintained in the relevant source code files.
 *
 *
 */

#if !defined(AFX_CODEEDITWND_H__99FF2A26_C2C7_11D2_80D0_000000000000__INCLUDED_)
#define AFX_CODEEDITWND_H__99FF2A26_C2C7_11D2_80D0_000000000000__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// CodeEditWnd.h : header file
//


#ifdef IDE_SUPPORT


/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

enum UndoTypes {
	utUndefined, utCut, utPaste,
};

class CUndoItem : public CObject {
public:
	CUndoItem();
	CUndoItem(UndoTypes type, CString text, int startLine, int startCol, int endLine, int endCol);
	CUndoItem(UndoTypes type, CString text, int startLine, int startCol, int endLine, int endCol,
		CString oldText, int delToLine, int delToCol);
	virtual ~CUndoItem();

	UndoTypes m_Type;
	CString m_Text;
	int m_StartLine;
	int m_StartCol;
	int m_EndLine;
	int m_EndCol;

	CString m_OldText;
	int m_DelToLine;
	int m_DelToCol;
};

class CUndoStack {
public:
	CUndoStack(int stackSize);
	virtual ~CUndoStack();

	void Clear();
	bool IsEmpty();
	bool IsRedoEmpty();
	void Push(CUndoItem* undoObject);
	CUndoItem* Pop();
	CUndoItem* PopRedo();

protected:
	void ClearRedo();
	int m_MaxStackSize;
	CObList m_UndoStack;
	CObList m_RedoStack;
};

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

class CTextBuffer {
	class CLineOfText : public CObject {
	public:
		CLineOfText(CString text, bool bBreakPoint = false)
			:m_Text(text),m_bBreakPoint(bBreakPoint){};
		virtual ~CLineOfText(){};
		CString m_Text;
		bool m_bBreakPoint;
		operator CString() {return m_Text;};
	};
public:
	CTextBuffer();
	CTextBuffer(CString text);
	virtual ~CTextBuffer();
	CPoint Undo(CPoint initCaretPos);
	CPoint Redo(CPoint initCaretPos);
	CPoint Paste(int startLine, int startCol, int endLine, int endCol);
	void Cut(int startLine, int startCol, int endLine, int endCol);
	void Copy(int startLine, int startCol, int endLine, int endCol);
	void Clear();
	CPoint CommentOut(int startLine, int startCol, int endLine, int endCol);
	CPoint Uncomment(int startLine, int startCol, int endLine, int endCol);
	CPoint Indent(int startLine, int startCol, int endLine, int endCol);
	CPoint Unindent(int startLine, int startCol, int endLine, int endCol);
	int LineCount();
	int LineLength(int line);
	void SetText(LPCTSTR text);
	CString GetLineOfText(int line);
	void GetLinesOfText(int startLine, int count, CString lines[], bool breakpoints[]);
	CString GetText(CString crStyle);
	CString GetText(CString crStyle, int firstLine, int lastLine);
	CString GetText(CString crStyle, int startLine, int startCol, int endLine, int endCol);
	bool LoadFromFile(CString filename);
	bool SaveToFile(CString filename, bool bUnicode);
	void SetBreakpoint(int line, bool bSet);	// bSet ? set : clear
	bool IsBreakpoint(int line);
	int BreakPointCount();
	bool CanUndo();
	bool CanRedo();
protected:
	CLineOfText* GetCLineOfText(int line);
	CObList m_Lines;		// Each item is a CLineOfText pointer
	int m_BreakPointCount;	// For quick tests (no list walking needed)

public:
	CPoint Replace(CString str, int startLine, int startCol, int endLine, int endCol);
protected:
	void Delete(int startLine, int startCol, int endLine, int endCol);
	CPoint Insert(TCHAR ch, int line, int column);
	CPoint Insert(CString str, int line, int column);
	void Delete(int line, int column);
	CPoint _Replace(CString str, int startLine, int startCol, int endLine, int endCol);
	CUndoStack* m_UndoStack;
};

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CCodeEditWnd window

class CCodeEditWnd : public CWnd
{
// Construction
public:
	CCodeEditWnd();

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CCodeEditWnd)
	public:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	protected:
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	//}}AFX_VIRTUAL

// Implementation
public:
	bool GetShowLineNumbers();
	void SetShowLineNumbers(bool bShow);
	bool Find(CString text, bool bMatchCase);
	void FlashLine(int line, COLORREF color);
	void SetCurrentLineMark(int line);
	bool IsBreakpoint(int line);
	void SetBreakpoint(int line, bool bBreak);
	void ToggleBreakpoint(int line);
	int LineCount();
	CString GetLineOfText(int line);
	CString GetText();
	void SetText(CString text);
	bool CanUndo();
	bool CanRedo();
	void Delete();
	void Redo();
	void SelectAll();
	void Undo();
	void Paste();
	void Cut();
	void Copy();
	void CommentOut();
	void Uncomment();
	void Indent();
	void Unindent();
	void ReplaceSel(CString text);
	void ScrollUpDown(int topLine);
	void ScrollLeftRight(int leftCol);
	int Create(int style, const RECT& rc, CWnd* parent, int id);
	virtual ~CCodeEditWnd();

	void SetReadOnly(bool bReadOnly);
	void SetModified(bool bModified);
	bool GetModified();
protected:
	bool m_bModified;
	bool m_bReadOnly;
	bool m_bShowLineNumbers;

	// Generated message map functions
protected:
	inline void PaintLine(CDC& dc, CString text, CRect& rc, int line,
		CPoint& start, CPoint& end);
	void TabAdjust(CPoint& point, bool bExpand);
	void SelectWordAt(int line, int column);
	void CorrectSelOrder(CPoint& start, CPoint& end);
	enum SelectionOp {selMaintain, selExtend, selRemove};

	void AdjustScrollBarSizes();
	int m_CurrentLineMark;
	CBrush m_BreakPointBrush;
	bool m_bLButtonDown;
	void UnmarkSelection();
	CPoint m_SelEnd;
	CPoint m_SelStart;
	int m_TopLine;
	int m_LeftCol;
	CTextBuffer m_TextBuffer;
	int LinesPerScreen();
	int ColsPerScreen();
	CPoint LineColToClient(CPoint point);
	CPoint ClientToLineCol(CPoint point, bool bNudge);
	int PointToArea(CPoint point);
	bool m_bShift;
	bool m_bControl;
	void CaretUp(bool bExtendSel = false);
	void CaretDown(bool bExtendSel = false);
	void CaretRight(bool bExtendSel = false);
	void CaretLeft(bool bExtendSel = false);
	void PlaceCaret(int line, int column, SelectionOp selOption, bool bScroll = false);
	int m_FontHeight;
	int m_FontWidth;
	CPoint m_CaretPos;
	int m_MarginWidth;
	CFont m_Font;
	CBrush m_BackgroundBrush;
	CBrush m_MarginBackgroundBrush;
	COLORREF m_rgbText;
	COLORREF m_rgbBackground;
	COLORREF m_rgbMarginText;
	COLORREF m_rgbMarginBackground;
	//{{AFX_MSG(CCodeEditWnd)
	afx_msg void OnPaint();
	afx_msg void OnSetFocus(CWnd* pOldWnd);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnTimer(UINT nIDEvent);
	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};


#endif // IDE_SUPPORT


/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_CODEEDITWND_H__99FF2A26_C2C7_11D2_80D0_000000000000__INCLUDED_)
